Tutorials
Getting started
Chart interface
Web components
Chart internals
Data integration
Customization
Frameworks and bundlers
Mobile development
Plug-ins
Compact Chart
Troubleshooting
Glossary
Reference
JSFiddles

AI Ready Charts

Disclaimer

This tutorial assumes a moderate familiarity with AI models, such as OpenAI's GPT, Google's Gemini, and Anthropic's Claude. Understanding the limitations and variations of the language model you choose is crucial, as some models offer more accurate or relevant results than others.

To achieve the best outcomes, it's essential to experiment with different models, their configurations, and your prompting. For example, GPT-4o has significantly more inherent knowledge than GPT-4o-mini, which means that a prompt for GPT-4o-mini will require more domain-specific knowledge. We recommend starting with a more complex model during early development to gain a clear understanding of its capabilities, and then experimenting with smaller, faster models to find the optimal balance of speed and efficiency for your project.

The way you format your prompt is crucial, as it influences how the language model interprets the input and responds. It is recommended to consult the documentation of the AI model you are using to implement your AI Ready features.

A sample prompt is included at the bottom of this tutorial.

Introduction

ChartIQ v9.7.0 introduces the executor function, enabling developers to leverage AI capabilities to transform how users interact with and analyze their data. This function allows AI to drive the chart by passing command line interface commands from outside the CLI Plugin, giving AI the ability to change the chart type, adjust the periodicity or range, add a study, add a series, reset the chart, and more.

Getting Started

This tutorial will guide you through the basic steps of setting up your executor function to accept input from a custom UI, such as an AI-powered chat agent.

For this tutorial, we'll be working with sample-template-basic.html.

Note: sample-template-basic.html is located within examples/templates and must be copied to the root directory for the import references to work.

Create A Reference

Ensure that the CLI plugin has been imported.

Then, create a reference to it.

import "./plugins/cli/cli.js";

const aiReady = document.querySelector("cq-cli");

Create Your Environment

This step is necessary if you are implementing a custom UI that will capture your natural language input, display any output, or both.

If you do not provide an environment, your executor can still function, but there will be no UI to display the responses returned. In other words, if your AI response is configured correctly, the chart will still be manipulated, but the responses will not be visible.

Modify existing HTML

  1. Add a style attribute to cq-context and set its width to 75%.
  2. Create the side panel and include a basic input field and submit button.
    • This is an example of where the end user might enter their natural language input for processing by the AI model.
<body>

<cq-context style="width: 75%;"><cq-chart-instructions></cq-chart-instructions>

<!-- Template Specific HTML -->

</cq-context>
<div id="sidePanel" style="width: 25%; position: fixed; right: 0;">
  <form id="aiInputForm">
    <input id="aiInputField" type="text" placeholder="Enter your command">
    <button type="submit">Submit</button>
  </form>
</div>

Override CLI methods

To interact with our newly created UI, we need to override the echo method from the aiReady reference. This is necessary because the executor function is bound to the CLI plugin and utilizes its echo and log methods by default. By overriding the echo method, we can control how we display any command output.

  1. Create a function to process text returned after running a command: In this example, we define the sidePanelEcho function, which creates a div, sets its innerText to the command's output, and appends it to the side panel. Note: Not all commands return text.

  2. Create a sidePanelEnv: This is an object that will hold the overridden methods and will be added to our aiReady reference when creating the executor in the next step.

  3. Override the aiReady echo method: Now, we assign our newly created sidePanelEcho method to the echo property of the sidePanelEnv object, effectively replacing the original echo method with our custom implementation.

function sidePanelEcho(text) {
  const node = document.createElement("div");
  node.innerText = text;
  document.getElementById("sidePanel").appendChild(node);
}

const sidePanelEnv = {}; // Define an object to hold overridden methods that will be added as prototypes to the CLI reference

// Override the `echo` method of CLI
sidePanelEnv.echo = sidePanelEcho;

Creating your executor

Finally, we will create our executor by calling the aiReady reference's getExecutor method. This method takes the 'environment' we created and modified in the previous step, along with the registry object, as arguments. You only need to include the registry object in getExecutor if you are adding custom commands to the registry from within your template.

Note: A passed registry will replace the built-in registry, so it's best to extend or modify the existing registry when adding custom commands.

Example:

import { registry } from "./plugins/cli/registry.js";
// ...
// ...
const updatedRegistry = { ...registry };

updatedRegistry.myCustomCommand = {
  func: function () {
    // ...
    // ...
  }
}
const executor = aiReady.getExecutor(sidePanelEnv, updatedRegistry); // Create executor with your modified registry object

As mentioned previously, if you are not utilizing a custom UI and methods, you do not need to provide the environment we created in the previous step and can simply call getExecutor() without any arguments.

const executor = aiReady.getExecutor(sidePanelEnv); // Create executor

Using the executor

With the executor defined, we can now pass commands using the executor method. Please refer to the CLI Tutorial for available commands and proper syntax.

This example utilizes the simple input we created in the earlier step to pass the value of the input to the executor.

// Add a submit event listener to the off-chart form
document.getElementById("aiInputForm").addEventListener("submit", (event) => {
  // Prevent the default form submission behavior
  event.preventDefault();

  // Get the input value and pass it to the executor function
  const inputValue = document.getElementById("aiInputField").value;
  executor(inputValue);

  // Reset the form after submission
  document.getElementById("aiInputForm").reset();
});

Using the executor with AI

Important: There are several nuanced steps involved in passing input to your AI and processing its response, which is why they are not included in this tutorial. Instead, use it as a starting point to configure your executor and prepare it to accept AI responses.


The UI we just built accepts valid CLI commands, such as type Line, prompting the chart to respond as if the command were entered directly into the CLI plugin's UI.

With AI, we can expand on this by executing commands generated from natural language input.

For example, a very simple prompt might look like this:

To display a specific chart type, write the following:
"type <chartType>"

Replace <chartType> with one of the following: Candle, Line, Mountain, Step, Histogram.

A user can type the message "Show me a histogram chart," and the model will respond with the command type Histogram, which you then pass into the executor.

We recommend limiting your model to JSON output for reliable responses.

Sample Prompt

Below is a sample prompt that was used in development of our AI Ready features and should serve as a good jumping off point for your own ChartIQ AI Ready implementations.

With a properly configured prompt, the AI model will generate a command based off of the user's natural language input, and return a JSON object containing the desired command and a message.


Here are a few things to note that are crucial for creating your own prompt:

  1. Provide Context: Our prompt begins by explaining what ChartIQ is and its visual layout, establishing a clear understanding of the user and defining the role for the AI model.

  2. Be Specific: The prompt provides a list of commands to the AI model, ensuring it knows the appropriate syntax to respond with. This is critical because, without the correct syntax, the executor cannot process the response. The prompt also instructs the model on how to reply to user requests.

  3. Structure the Response: Specify that the response should be in JSON format, detailing the structure. This allows for easy integration with the executor function.

  4. This is only an example: Your prompt should be specific to your charting application, its features, and the terminology your users will use.

You are in control of a charting program called "ChartIQ". ChartIQ is a time-series chart used to visualize financial data. 
A ChartIQ chart will have two axis. The X axis will indicate a span of time. The Y axis will indicate a data value, usually a price.

You will receive a request from the user. 
You will receive a list of text commands that control the chart. 

You will read the user's request and determine which of the text commands best matches the user's request. 

Your response will be in the form of a json object with the following structure:
{
    "message": "A message to the user"
    "cmd": [],
}

The "message" field will contain the message to be displayed to the user. 
- If the user asks a question, do your best to answer the question in the message only if the question is related to the chart.
- If the message is ambiguous, respond with a helpful suggestion of how to clarify the request.
- if you do not have an answer, you can respond with "I don't have an answer to that question". 
- The message should provide a narration explaining each command.
- The message should be as short as possible.
The "cmd" field will contain an array of commands that best fit the user's request.
If no command fits the user's request. You will respond with the command "unknown".

Today's date is ${today}.

List of Commands
- "type <chartType>": <chartType> must be one of the following "Line", "Step", "Mountain", "Candle", "Bar", "Histogram".
- "symbol <symbol>": The command parameter must be a valid stock symbol. If you're not sure of the stock symbol. Ask for a valid stock symbol.
- "range <start date> <end date>": <startDate> and <endDate> must be valid dates in the format "MM/DD/YYYY". To show a single day, {startDate} and {endDate} should be the same.
- "home" Scrolls the chart to the latest point in time.
- "periodicity '[period]'" Change the period or interval of time that each point on the chart represents. Valid values are "1 D", "1 W", "1 Mo", "1 Min", "5 Min", "10 Min", "15 Min", "30 Min", "1 Hour", "4 Hour", "1 Sec", "10 Sec", "30 Sec", "250 MSec"
- "polling [start|stop]" Controls live updating of data.
- "reset -f" Reset the chart to defaults and reload the page. Only use this option if you are sure you want to reload the page.
- "series [-c] [-rx] <symbol> [color]" Add or remove a series; <symbol> must me a valid stock symbol. Use the -c option to add as a comparison series, and the -r option to remove (or -x to remove all).
- "study [-l] [-rx] <study name>" Add or remove a study; <study name> must be a valid study name and wrapped in quotes. Use the -l option to list available studies, and the -r option to remove (or -x to remove all).

Additional Instructions
- When removing a study, the user must provide the name of the study, from the chart legend, in quotes. For example: "ma (50,ma,0)". If they are having trouble removing a study, remind them of this.

Study Names:
- "Anchored VWAP"
- "Median Price"
- "Momentum Indicator"
- "Moving Average"
- "Moving Average Cross"
- "Price Rate of Change"
- "Price Relative"
- "Standard Deviation"
- "True Range"
- "Volume Chart"
- "VWAP"
- "ZigZag"

Example AI Response

Using the above prompt with the following request, "Change the chart type to a line chart," the expected AI response would be something like:

{
  "message": "I will change the chart type to a Line chart.",
  "cmd": [
    "type Line"
  ]
}

The values in the cmd array would then be passed into the executor: executor("type Line"), while the message string can be used to provide feedback to the user.

Next Steps

To learn more about the CLI plugin, as well as how to customize or create your own commands, check out the CLI Tutorial.